const fs = require('fs-extra');
const path = require('path');
const glob = require('glob');

/**
 * Metadata依赖关系分析器
 * 扫描metadata目录中的JSON文件，分析依赖关系并输出结果
 */

// 存储所有JSON文件的name映射
let nameToFileMap = new Map();

/**
 * 扫描metadata目录中的所有JSON文件
 */
async function scanJsonFiles() {
    const metadataPath = path.join(__dirname, '..', 'metadata');
    const jsonFiles = glob.sync('**/*.json', { cwd: metadataPath });
    
    console.log(`正在扫描metadata目录...`);
    console.log(`找到 ${jsonFiles.length} 个JSON文件`);
    
    const fileData = [];
    let processedCount = 0;
    
    for (const file of jsonFiles) {
        try {
            const filePath = path.join(metadataPath, file);
            const content = await fs.readJson(filePath);
            
            if (content.name) {
                nameToFileMap.set(content.name, file);
                fileData.push({
                    file: file,
                    name: content.name,
                    title: content.title || '',
                    dependencies: content.dependencies || [],
                    category: content.category || 'unknown',
                    define: content.define || ''
                });
                processedCount++;
                
                if (processedCount % 100 === 0) {
                    console.log(`已处理 ${processedCount}/${jsonFiles.length} 个文件`);
                }
            }
        } catch (error) {
            console.warn(`解析文件失败: ${file}`, error.message);
        }
    }
    
    console.log(`扫描完成，成功处理 ${processedCount} 个文件`);
    return fileData;
}

/**
 * 构建依赖关系图
 */
function buildDependencyGraph(fileData) {
    console.log('正在构建依赖关系图...');
    
    const nodes = [];
    const edges = [];
    const seenNodes = new Set();
    const seenEdges = new Set();
    
    // 创建节点 - 去重处理
    fileData.forEach((file, index) => {
        if (!seenNodes.has(file.name)) {
            seenNodes.add(file.name);
            const node = {
                id: file.name,
                label: file.title || file.name,
                file: file.file,
                category: file.category,
                define: file.define,
                dependencies: file.dependencies,
                group: getCategoryGroup(file.category)
            };
            
            nodes.push(node);
        }
    });
    
    // 创建边（依赖关系）- 去重处理
    let validDependencies = 0;
    let invalidDependencies = 0;
    
    fileData.forEach(file => {
        if (file.dependencies && file.dependencies.length > 0) {
            file.dependencies.forEach(dep => {
                // 检查依赖是否存在对应的文件
                if (nameToFileMap.has(dep)) {
                    const edgeKey = `${file.name}-${dep}`;
                    if (!seenEdges.has(edgeKey)) {
                        seenEdges.add(edgeKey);
                        const edge = {
                            from: file.name,
                            to: dep,
                            label: 'depends on',
                            arrows: 'to'
                        };
                        edges.push(edge);
                        validDependencies++;
                    }
                } else {
                    invalidDependencies++;
                }
            });
        }
    });
    
    console.log(`构建完成:`);
    console.log(`- 节点数: ${nodes.length}`);
    console.log(`- 有效依赖关系: ${validDependencies}`);
    console.log(`- 无效依赖关系: ${invalidDependencies}`);
    
    return { nodes, edges };
}

/**
 * 根据category获取分组
 */
function getCategoryGroup(category) {
    const categoryGroups = {
        'bill': 1,
        'datamodel': 2,
        'approve': 3,
        'basedata': 4,
        'querysource': 5,
        'queryview': 6,
        'print': 7,
        'invoice': 8,
        'message': 9,
        'workflowQuery': 10
    };
    
    return categoryGroups[category] || 0;
}

/**
 * 生成过滤掉超级节点的可视化数据
 */
function generateFilteredVisualizationData(dependencyGraph, analysis, superNodeIds) {
    console.log('正在生成过滤版本的可视化数据...');
    
    // 过滤掉超级节点
    const filteredNodes = dependencyGraph.nodes.filter(node => !superNodeIds.includes(node.id));
    
    // 过滤掉与超级节点相关的边
    const filteredEdges = dependencyGraph.edges.filter(edge => 
        !superNodeIds.includes(edge.from) && !superNodeIds.includes(edge.to)
    );
    
    // 重新计算统计信息
    const filteredNodeIds = new Set(filteredNodes.map(node => node.id));
    const filteredConnectedNodes = new Set();
    
    filteredEdges.forEach(edge => {
        filteredConnectedNodes.add(edge.from);
        filteredConnectedNodes.add(edge.to);
    });
    
    const filteredIsolatedNodes = filteredNodes.filter(node => !filteredConnectedNodes.has(node.id)).length;
    
    return {
        nodes: filteredNodes.map(node => ({
            id: node.id,
            label: node.label,
            file: node.file,
            category: node.category,
            group: node.group,
            dependencies: node.dependencies
        })),
        edges: filteredEdges,
        categories: [...new Set(filteredNodes.map(node => node.category))],
        stats: {
            totalNodes: filteredNodes.length,
            totalEdges: filteredEdges.length,
            isolatedNodes: filteredIsolatedNodes,
            filteredSuperNodes: superNodeIds.length,
            originalNodes: dependencyGraph.nodes.length,
            originalEdges: dependencyGraph.edges.length
        },
        filterInfo: {
            filteredAt: new Date().toISOString(),
            superNodeIds: superNodeIds,
            superNodeDetails: superNodeIds.map(id => {
                const nodeInfo = analysis.nodeInfo.get(id);
                const dependentCount = analysis.nodeDependentCount.get(id) || 0;
                return {
                    id,
                    title: nodeInfo ? nodeInfo.title : id,
                    category: nodeInfo ? nodeInfo.category : 'unknown',
                    dependentCount
                };
            })
        }
    };
}

/**
 * 分析间接依赖关系
 */
function analyzeIndirectDependencies(nodes, edges) {
    console.log('正在分析间接依赖关系...');
    
    const indirectStats = {
        maxIndirectDepth: 0,
        averageIndirectDepth: 0,
        complexDependencies: [], // 复杂依赖链
        circularDependencies: [] // 循环依赖
    };
    
    const nodeDepths = new Map();
    const visited = new Set();
    const recursionStack = new Set();
    
    // 计算每个节点的最大依赖深度
    function calculateDepth(nodeId, depth = 0) {
        if (recursionStack.has(nodeId)) {
            // 发现循环依赖
            indirectStats.circularDependencies.push(nodeId);
            return depth;
        }
        
        if (visited.has(nodeId)) {
            return nodeDepths.get(nodeId) || 0;
        }
        
        visited.add(nodeId);
        recursionStack.add(nodeId);
        
        let maxChildDepth = depth;
        const outgoingEdges = edges.filter(edge => edge.from === nodeId);
        
        for (const edge of outgoingEdges) {
            const childDepth = calculateDepth(edge.to, depth + 1);
            maxChildDepth = Math.max(maxChildDepth, childDepth);
        }
        
        nodeDepths.set(nodeId, maxChildDepth);
        indirectStats.maxIndirectDepth = Math.max(indirectStats.maxIndirectDepth, maxChildDepth);
        
        recursionStack.delete(nodeId);
        return maxChildDepth;
    }
    
    // 计算所有节点的深度
    nodes.forEach(node => {
        if (!visited.has(node.id)) {
            calculateDepth(node.id);
        }
    });
    
    // 计算平均深度
    const totalDepth = Array.from(nodeDepths.values()).reduce((sum, depth) => sum + depth, 0);
    indirectStats.averageIndirectDepth = totalDepth / nodeDepths.size;
    
    // 找出复杂依赖链（深度大于3的节点）
    nodeDepths.forEach((depth, nodeId) => {
        if (depth > 3) {
            const node = nodes.find(n => n.id === nodeId);
            if (node) {
                indirectStats.complexDependencies.push({
                    id: nodeId,
                    title: node.title || node.label,
                    depth: depth,
                    category: node.category
                });
            }
        }
    });
    
    // 按深度排序
    indirectStats.complexDependencies.sort((a, b) => b.depth - a.depth);
    
    return indirectStats;
}

/**
 * 分析依赖关系统计
 */
function analyzeDependencies(nodes, edges) {
    console.log('\n正在分析依赖关系统计...');
    
    // 统计各分类的节点数量
    const categoryStats = {};
    nodes.forEach(node => {
        categoryStats[node.category] = (categoryStats[node.category] || 0) + 1;
    });
    
    // 统计节点的依赖和被依赖情况
    const dependencyStats = {
        noDependencies: 0,      // 无依赖的节点
        noDependents: 0,        // 无被依赖的节点
        isolated: 0,            // 独立节点（既无依赖也无被依赖）
        maxDependencies: 0,     // 最大依赖数
        maxDependents: 0        // 最大被依赖数
    };
    
    const nodeDependencyCount = new Map();
    const nodeDependentCount = new Map();
    const nodeInfo = new Map(); // 存储节点详细信息
    
    // 初始化计数和节点信息
    nodes.forEach(node => {
        nodeDependencyCount.set(node.id, 0);
        nodeDependentCount.set(node.id, 0);
        nodeInfo.set(node.id, {
            id: node.id,
            title: node.title || node.label,
            category: node.category,
            file: node.file
        });
    });
    
    // 统计依赖关系
    edges.forEach(edge => {
        nodeDependencyCount.set(edge.from, nodeDependencyCount.get(edge.from) + 1);
        nodeDependentCount.set(edge.to, nodeDependentCount.get(edge.to) + 1);
    });
    
    // 分析统计
    nodes.forEach(node => {
        const depCount = nodeDependencyCount.get(node.id);
        const dependentCount = nodeDependentCount.get(node.id);
        
        if (depCount === 0) dependencyStats.noDependencies++;
        if (dependentCount === 0) dependencyStats.noDependents++;
        if (depCount === 0 && dependentCount === 0) dependencyStats.isolated++;
        
        dependencyStats.maxDependencies = Math.max(dependencyStats.maxDependencies, depCount);
        dependencyStats.maxDependents = Math.max(dependencyStats.maxDependents, dependentCount);
    });
    
    // 分析间接依赖
    const indirectDependencies = analyzeIndirectDependencies(nodes, edges);
    
    return {
        categoryStats,
        dependencyStats,
        nodeDependencyCount,
        nodeDependentCount,
        nodeInfo,
        indirectDependencies
    };
}

/**
 * 保存分析结果
 */
async function saveResults(dependencyGraph, analysis) {
    const outputDir = path.join(__dirname, 'output');
    await fs.ensureDir(outputDir);
    
    // 保存完整的依赖关系数据
    const fullData = {
        ...dependencyGraph,
        analysis,
        metadata: {
            generatedAt: new Date().toISOString(),
            totalNodes: dependencyGraph.nodes.length,
            totalEdges: dependencyGraph.edges.length
        }
    };
    
    await fs.writeJson(path.join(outputDir, 'dependency-analysis.json'), fullData, { spaces: 2 });
    
    // 保存简化的可视化数据
    const visualizationData = {
        nodes: dependencyGraph.nodes.map(node => ({
            id: node.id,
            label: node.label,
            file: node.file,
            category: node.category,
            group: node.group,
            dependencies: node.dependencies
        })),
        edges: dependencyGraph.edges,
        categories: Object.keys(analysis.categoryStats),
        stats: {
            totalNodes: dependencyGraph.nodes.length,
            totalEdges: dependencyGraph.edges.length,
            isolatedNodes: analysis.dependencyStats.isolated
        }
    };
    
    await fs.writeJson(path.join(outputDir, 'visualization-data.json'), visualizationData, { spaces: 2 });
    
    // 检查是否有被依赖数大于30的超级节点
    const superNodes = Array.from(analysis.nodeDependentCount.entries())
        .filter(([id, count]) => count > 10)
        .map(([id, count]) => ({ id, count }));
    
    if (superNodes.length > 0) {
        console.log(`\n发现 ${superNodes.length} 个超级节点（被依赖数 > 10），生成过滤版本...`);
        
        // 生成过滤掉超级节点的可视化数据
        const filteredVisualizationData = generateFilteredVisualizationData(
            dependencyGraph, 
            analysis, 
            superNodes.map(node => node.id)
        );
        
        await fs.writeJson(path.join(outputDir, 'visualization-data-filtered.json'), filteredVisualizationData, { spaces: 2 });
        
        console.log('已生成过滤版本: visualization-data-filtered.json');
        console.log('过滤掉的超级节点:');
        superNodes.forEach(node => {
            const nodeInfo = analysis.nodeInfo.get(node.id);
            const title = nodeInfo ? nodeInfo.title : node.id;
            console.log(`  - ${title} (${node.id}): ${node.count} 个被依赖`);
        });
    }
    
    // 保存统计报告
    const report = {
        generatedAt: new Date().toISOString(),
        summary: {
            totalFiles: dependencyGraph.nodes.length,
            totalDependencies: dependencyGraph.edges.length,
            isolatedNodes: analysis.dependencyStats.isolated,
            maxIndirectDepth: analysis.indirectDependencies.maxIndirectDepth,
            averageIndirectDepth: Math.round(analysis.indirectDependencies.averageIndirectDepth * 100) / 100,
            circularDependencies: analysis.indirectDependencies.circularDependencies.length
        },
        categoryBreakdown: analysis.categoryStats,
        dependencyAnalysis: analysis.dependencyStats,
        indirectDependencyAnalysis: {
            maxIndirectDepth: analysis.indirectDependencies.maxIndirectDepth,
            averageIndirectDepth: Math.round(analysis.indirectDependencies.averageIndirectDepth * 100) / 100,
            complexDependenciesCount: analysis.indirectDependencies.complexDependencies.length,
            circularDependenciesCount: analysis.indirectDependencies.circularDependencies.length,
            circularDependencies: analysis.indirectDependencies.circularDependencies
        },
        topDependencies: Array.from(analysis.nodeDependencyCount.entries())
            .sort((a, b) => b[1] - a[1])
            .slice(0, 15)
            .map(([id, count]) => {
                const nodeInfo = analysis.nodeInfo.get(id);
                return {
                    id,
                    title: nodeInfo ? nodeInfo.title : id,
                    category: nodeInfo ? nodeInfo.category : 'unknown',
                    file: nodeInfo ? nodeInfo.file : '',
                    count
                };
            }),
        topDependents: Array.from(analysis.nodeDependentCount.entries())
            .sort((a, b) => b[1] - a[1])
            .slice(0, 15)
            .map(([id, count]) => {
                const nodeInfo = analysis.nodeInfo.get(id);
                return {
                    id,
                    title: nodeInfo ? nodeInfo.title : id,
                    category: nodeInfo ? nodeInfo.category : 'unknown',
                    file: nodeInfo ? nodeInfo.file : '',
                    count
                };
            }),
        complexDependencies: analysis.indirectDependencies.complexDependencies.slice(0, 20),
        categoryAnalysis: Object.entries(analysis.categoryStats).map(([category, count]) => {
            const categoryNodes = dependencyGraph.nodes.filter(node => node.category === category);
            const categoryEdges = dependencyGraph.edges.filter(edge => {
                const fromNode = dependencyGraph.nodes.find(n => n.id === edge.from);
                const toNode = dependencyGraph.nodes.find(n => n.id === edge.to);
                return fromNode && toNode && (fromNode.category === category || toNode.category === category);
            });
            
            return {
                category,
                nodeCount: count,
                edgeCount: categoryEdges.length,
                averageDependencies: categoryNodes.length > 0 ? 
                    Math.round((categoryEdges.length / categoryNodes.length) * 100) / 100 : 0
            };
        }).sort((a, b) => b.nodeCount - a.nodeCount)
    };
    
    await fs.writeJson(path.join(outputDir, 'analysis-report.json'), report, { spaces: 2 });
    
    console.log(`\n分析结果已保存到 ${outputDir} 目录:`);
    console.log('- dependency-analysis.json: 完整依赖关系数据');
    console.log('- visualization-data.json: 可视化数据');
    console.log('- analysis-report.json: 分析报告');
    
    if (superNodes.length > 0) {
        console.log('- visualization-data-filtered.json: 过滤超级节点的可视化数据');
    }
}

/**
 * 打印分析报告
 */
function printReport(analysis) {
    console.log('\n=== 依赖关系分析报告 ===');
    
    console.log('\n📊 分类统计:');
    Object.entries(analysis.categoryStats)
        .sort((a, b) => b[1] - a[1])
        .forEach(([category, count]) => {
            console.log(`  ${category}: ${count} 个文件`);
        });
    
    console.log('\n🔗 依赖关系统计:');
    console.log(`  无依赖的节点: ${analysis.dependencyStats.noDependencies}`);
    console.log(`  无被依赖的节点: ${analysis.dependencyStats.noDependents}`);
    console.log(`  独立节点: ${analysis.dependencyStats.isolated}`);
    console.log(`  最大依赖数: ${analysis.dependencyStats.maxDependencies}`);
    console.log(`  最大被依赖数: ${analysis.dependencyStats.maxDependents}`);
    
    console.log('\n🌐 间接依赖分析:');
    console.log(`  最大间接深度: ${analysis.indirectDependencies.maxIndirectDepth}`);
    console.log(`  平均间接深度: ${Math.round(analysis.indirectDependencies.averageIndirectDepth * 100) / 100}`);
    console.log(`  复杂依赖链: ${analysis.indirectDependencies.complexDependencies.length} 个`);
    console.log(`  循环依赖: ${analysis.indirectDependencies.circularDependencies.length} 个`);
    
    console.log('\n🏆 依赖最多的节点:');
    Array.from(analysis.nodeDependencyCount.entries())
        .sort((a, b) => b[1] - a[1])
        .slice(0, 5)
        .forEach(([id, count], index) => {
            const nodeInfo = analysis.nodeInfo.get(id);
            const title = nodeInfo ? nodeInfo.title : id;
            console.log(`  ${index + 1}. ${title} (${id}): ${count} 个依赖`);
        });
    
    console.log('\n🎯 被依赖最多的节点:');
    Array.from(analysis.nodeDependentCount.entries())
        .sort((a, b) => b[1] - a[1])
        .slice(0, 5)
        .forEach(([id, count], index) => {
            const nodeInfo = analysis.nodeInfo.get(id);
            const title = nodeInfo ? nodeInfo.title : id;
            console.log(`  ${index + 1}. ${title} (${id}): ${count} 个被依赖`);
        });
    
    if (analysis.indirectDependencies.complexDependencies.length > 0) {
        console.log('\n🔗 复杂依赖链 (深度 > 3):');
        analysis.indirectDependencies.complexDependencies.slice(0, 5).forEach((dep, index) => {
            console.log(`  ${index + 1}. ${dep.title} (${dep.id}): 深度 ${dep.depth}`);
        });
    }
    
    if (analysis.indirectDependencies.circularDependencies.length > 0) {
        console.log('\n⚠️  循环依赖节点:');
        analysis.indirectDependencies.circularDependencies.slice(0, 5).forEach((id, index) => {
            const nodeInfo = analysis.nodeInfo.get(id);
            const title = nodeInfo ? nodeInfo.title : id;
            console.log(`  ${index + 1}. ${title} (${id})`);
        });
    }
}

/**
 * 主函数
 */
async function main() {
    try {
        console.log('🚀 开始分析metadata依赖关系...\n');
        
        // 扫描JSON文件
        const fileData = await scanJsonFiles();
        
        // 构建依赖关系图
        const dependencyGraph = buildDependencyGraph(fileData);
        
        // 分析依赖关系
        const analysis = analyzeDependencies(dependencyGraph.nodes, dependencyGraph.edges);
        
        // 打印报告
        printReport(analysis);
        
        // 保存结果
        await saveResults(dependencyGraph, analysis);
        
        console.log('\n✅ 分析完成！');
        
    } catch (error) {
        console.error('❌ 分析失败:', error);
        process.exit(1);
    }
}

// 如果直接运行此文件
if (require.main === module) {
    main();
}

module.exports = {
    scanJsonFiles,
    buildDependencyGraph,
    analyzeDependencies,
    saveResults
};
